import java.util.Random;
import java.util.Scanner;

public class TestModelOne {

    //main方法，程序入口
    public static void main(String[] age) {
        TestModelOne tmo = new TestModelOne();
        //试题1
        //tmo.Test_01();
        //试题2
        //tmo.Test_02();
        //试题3
        //tmo.Test_03();
        //试题4
        //tmo.Test_04();
        //试题5
        //tmo.Test_05();
    }

    /*
        编程实现提示用户输入年月日信息，判断这一天是这一年中的第几天并打印。
    */

    public void Test_01() {
        //声明boolean类型变量，用于while循环体，预期达到效果如果用户输入年月日有误，可以重新输入，若输入正确，返回年月日信息，结束循环
        boolean b = true;
        //while循环，当b等于true进行无限循环，当b等于false时结束循环
        while (true == b) {
            //Scanner扫描器，从控制台获取数据
            Scanner scanner = new Scanner(System.in);
            System.out.print("请输入年:");
            //年
            int year = scanner.nextInt();
            System.out.print("请输入月:");
            //月
            int month = scanner.nextInt();
            System.out.print("请输入日:");
            //日
            int day = scanner.nextInt();
            //声明记录天数变量，并初始化
            int day_sum = 0;
            //创建数组记录1,3,5,7,8,10,12月份
            int month_num[] = {1, 3, 5, 7, 8, 10, 12};
            //创建数组记录1-12月闰年每月天数，此处2月以29记录，为闰2月
            int day_num[] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};


            //普通闰年:公历年份是4的倍数的，且不是100的倍数，为普通闰年。（如2004、2020年就是闰年）；
            //世纪闰年:公历年份是整百数的，必须是400的倍数才是世纪闰年（如1900年不是世纪闰年，2000年是世纪闰年）；
            if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) {

                //System.out.println("闰年");
                //1 3 5 7 8 10 12 31天
                //4 6 9 11  30天
                //2 29天

                    //判断所输入月份和日期是否规范，要求月必须在1-12之内包含1和12，日必须在1-31之内，包含1和31
                    if (year > 0 && month >= 1 && month <= 12 && day >= 1 && day <= 31) {

                        //System.out.println(day_sum);
                        //for遍历，计算当前月份之前的月份总天数
                        for (int d = 0; d < month-1 ; d++) {
                            //System.out.println("d----->"+d);
                            day_sum += day_num[d];
                            //System.out.println("---------"+month_num[i]);

                        }
                        //判断月份
                        //1 3 5 7 8 10 12天数为31天
                        //4 6 9 11天数为30天
                        //闰2月天数为29天
                        //System.out.println(month);
                        for (int i = 0; i < month_num.length; i++) {
                            if (month == month_num[i]) {
                                //System.out.println("1 3 5 7 8 10 12 31天" + month);
                                //打印结果，如：您输入的时闰年2020年3月3日
                                System.out.println("您输入的是闰年" + year + "年" + month + "月" + day + "日");
                                //System.out.println(day_sum);
                                //打印结果，如：第63天
                                System.out.println("第" + (day_sum + day) + "天");    //day_sum+day 实现当前月份之前的月份天数+当前月份的天数的总和
                                b = false;    //年月日输出成功，赋值b为false，结束while循环
                                break;
                            } else if (month != month_num[i] && month != 2 && day <= 30) {       //4 6 9 11天数为30天
                                //System.out.println("4 6 9 11  30天" + month);
                                //打印结果，如：您输入的时闰年2020年4月4日
                                System.out.println("您输入的是闰年" + year + "年" + month + "月" + day + "日");
                                //打印结果，如：第95天
                                System.out.println("第" + (day_sum + day) + "天");    //day_sum+day 实现当前月份之前的月份天数+当前月份的天数的总和
                                b = false;    //年月日输出成功，赋值b为false，结束while循环
                                break;  //停止for循环，达到效果只打印一次结果
                            } else if (day <= 29) {     //闰2月天数为29天，判断如果用户输入大于29天则不执行以下else if中的语句块
                                System.out.println("您输入的是闰年" + year + "年" + month + "月" + day + "日");
                                System.out.println("第" + (day_sum + day) + "天");    //day_sum+day 实现当前月份之前的月份天数+当前月份的天数的总和
                                b = false;    //年月日输出成功，赋值b为false，结束while循环
                                break;
                            }
                        }



                    } else {
                        System.out.println("您所输入的年或者月份或者日期有误");

                    }
                //}
                //System.out.println(month_num[i]);


            } else {

                //System.out.println("平年");
                //1 3 5 7 8 10 12 31天
                //4 6 9 11  30天
                //2 28天

                    //判断所输入月份和日期是否规范，要求月必须在1-12之内包含1和12，日必须在1-31之内，包含1和31
                    if (year > 0 && month >= 1 && month <= 12 && day >= 1 && day <= 31) {
                        //for遍历，计算当前月份之前的月份总天数
                        for (int d = 0; d < month - 1; d++) {
                            //System.out.println("d----->"+d);
                            day_sum += day_num[d];
                        }

                        //System.out.println(day_sum);

                        //判断月份
                        //1 3 5 7 8 10 12天数为31天
                        //4 6 9 11天数为30天
                        //闰2月天数为29天
                        for (int i = 0; i < month_num.length; i++) {
                            if (month == month_num[i]) {
                                //System.out.println("1 3 5 7 8 10 12 31天" + month);
                                System.out.println("您输入的是平年" + year + "年" + month + "月" + day + "日");
                                //System.out.println(day_sum);
                                ////day_sum+day 实现当前月份之前的月份天数+当前月份的天数的总和
                                System.out.println("第" + (day_sum + day - 1) + "天");    //由于day_num数组中的2月份记录的是闰年的29天，所以此处需要减1
                                b = false;    //年月日输出成功，赋值b为false，结束while循环
                                break;
                            } else if (month != month_num[i] && month != 2) {       //4 6 9 11天数为30天
                                //System.out.println("4 6 9 11  30天" + month);
                                System.out.println("您输入的是平年" + year + "年" + month + "月" + day + "日");
                                //day_sum+day 实现当前月份之前的月份天数+当前月份的天数的总和
                                System.out.println("第" + (day_sum + day - 1) + "天");    //由于day_num数组中的2月份记录的是闰年的29天，所以此处需要减1
                                b = false;    //年月日输出成功，赋值b为false，结束while循环
                                break;
                            } else if (day <= 28) {     //平2月天数为28天
                                System.out.println("您输入的是平年" + year + "年" + month + "月" + day + "日");
                                System.out.println("第" + (day_sum + day) + "天");    //day_sum+day 实现当前月份之前的月份天数+当前月份的天数的总和
                                b = false;    //年月日输出成功，赋值b为false，结束while循环
                                break;
                            }
                        }

                    } else {
                        System.out.println("您所输入的年或者月份或者日期有误");

                    }

                    //System.out.println(month_num[i]);

                //}
            }
        }
    }


    /*
        编程实现编程找出 1000 以内的所有完数并打印出来。
        所谓完数就是一个数恰好等于它的因子之和，如：6=1＋2＋3
    */
    public void Test_02() {

        //声明记录完数变量
        int num = 0;
        //for循环实现1～1000
        for (int i = 1; i <= 1000; i++) {
            //双重for实现1～999，此处j<i，是因为完数等于它因子之和，且不包含本身
            for (int j = 1; j < i; j++) {
                //完数：完数就是一个数恰好等于它的因子之和，如：6=1＋2＋3
                //1 * 6 = 6
                //2 * 3 = 6
                //商除以被除数==除数，余数为0，则成立  //及6/3=2，则余数为0
                if (i % j == 0) {
                    //System.out.println("j>>>>>>" + num);
                    //判断如果i取余，余数为0时，则记录j值，且将j值赋值给num且累加num之前的值，为num=num+j
                    num += j;
                }

            }
            //判断如果num==i，则记录num（完数）
            if (num == i) {
                System.out.println("完数：" + num);
            }
            //此处为每次记录完数后，避免被累加到下一次完数备份，故赋值为0
            num = 0;
            //System.out.println("i====" + i);
        }

    }


    /*
        编程实现双色球抽奖游戏中奖号码的生成，中奖号码由 6 个红球号码和 1 个蓝球号码组成。
        其中红球号码要求随机生成 6 个 1~33 之间不重复的随机号码。
        其中蓝球号码要求随机生成 1 个 1~16 之间的随机号码
    */
    public void Test_03() {
        //用于生成随机数，调用Random
        Random random = new Random();
        //声明数组，空间为6
        int[] nums = new int[6];
        //for循环用于实现将随机数赋值与nums数组
        for (int i = 0; i < nums.length; i++) {
            //将1-33的随机数赋值给nums数组
            nums[i] = random.nextInt(33) + 1;
            //使用for循环判断如果所产生6个的随机数中如果有重复的数据，则将i-1，重新给上一个下标生成随机数，直到不重复为止
            for (int j = 0; j < i; j++) {
                //判断所产生6个的随机数中是否存有重复数据
                if (nums[i] == nums[j]) {
                    //将i-1，重新给上一个下标生成随机数
                    i--;
                    break;
                }
            }

        }
        System.out.print("红球号码为：");
        //for循环用于打印输出数组值
        for (int a = 0; a < nums.length; a++) {
            System.out.print(nums[a] + ",");
        }
        System.out.println();
        //生成1-16任意一个随机数并输出
        System.out.println("蓝球号码为：" + (random.nextInt(16) + 1));

    }


    /*
        编程实现自定义数组扩容规则，当已存储元素数量达到总容量的 80%时，扩容 1.5 倍。
        例如，总容量是 10，当输入第 8 个元素时，数组进行扩容，容量从 10 变 15。
     */
    public void Test_04() {

        //声明记录数组空间变量，并初始化
        int a = 10;
        //声明数组
        int[] arr_1 = new int[a];
        //System.out.println(arr_1.length);
        //使用for循环实现提示用户输入元素，并且给arr_1数组赋值
        for (int i = 0; i < arr_1.length; i++) {
            //扫描器，从控制台获取数据
            Scanner scanner = new Scanner(System.in);
            //提示用户输入信息
            System.out.print("请输入" + (i + 1) + "个数字：");
            int number = scanner.nextInt();
            //将用户所输入的数值赋值给arr_1数组
            arr_1[i] = number;
            //if判断如果下标除以80%等于数组长度，则表示目前数组已使用80%需要进行扩容
            if ((i + 1) / 0.8 == arr_1.length) {
                System.out.print("目前为" + a + "已使用80%\t");
                //此时数组已使用80%需要进行扩容，a乘以1.5，由于1.5为double类型，所以a*1.5需要做类型转换为int
                a = (int) (a * 1.5);
                System.out.println("扩容1.5倍后为：" + a + "请放心继续使用");
            }

        }
        System.out.print("原始数组：");
        //使用for循环打印输出arr_1数组
        for (int v = 0; v < arr_1.length; v++) {
            System.out.print("[" + arr_1[v] + "]");
        }
        System.out.println();
        //声明扩容后的数组
        int[] arr_a = new int[a];
        //使用for循环，将arr_1数组中的值赋值于arr_a数组
        for (int j = arr_1.length; j > 0; j--) {
            //将arr_1数组下标对应的值赋值给arr_a数组相应下标上
            arr_a[j - 1] = arr_1[j - 1];
            //System.out.print(arr_a[j]);
        }
        System.out.print("扩容1.5倍后的数组：");
        //使用for循环打印输出arr_a数组
        for (int c = 0; c < arr_a.length; c++) {
            System.out.print("[" + arr_a[c] + "]");
        }


    }



    /*
        编程实现使用双重循环实现五子棋游戏棋盘的绘制，棋盘界面的具体效果如下
     */

    public void Test_05() {
        //使用for循环实现第一行从0-15
        for (int nn = 0; nn <= 15; nn++) {
            //if判断如果nn小于等于9的话，打印0之9数字
            if (nn <= 9) {
                //打印0-9，使用\t输入空格，保证格式一致
                System.out.print("\t" + nn + "\t");
            } else {
                //如果大于9的话使用switch case，当nn=10时打印a,依此类推，15打印f，实现10-15为字母打印
                switch (nn) {
                    //当nn=10时打印a
                    case 10:
                        System.out.print("\ta\t");
                        break;  //此处break主要作用用于中断
                    //当nn=11时打印b
                    case 11:
                        System.out.print("\tb\t");
                        break;  //此处break主要作用用于中断
                    //当nn=12时打印c
                    case 12:
                        System.out.print("\tc\t");
                        break;  //此处break主要作用用于中断
                    //当nn=13时打印d
                    case 13:
                        System.out.print("\td\t");
                        break;  //此处break主要作用用于中断
                    //当nn=14时打印e
                    case 14:
                        System.out.print("\te\t");
                        break;  //此处break主要作用用于中断
                    //当nn=15时打印f
                    case 15:
                        System.out.print("\tf\t");
                        break;  //此处break主要作用用于中断
                }
            }
        }
        //换行
        System.out.println();
        //使用外层for循环实现0-15行
        for (int i = 0; i <= 15; i++) {
            if (i <= 9) {
                System.out.print(i);
            } else {
                //如果大于9的话使用switch case，当i=10时打印a,依此类推，15打印f，实现10-15为字母打印
                switch (i) {
                    //当i=10时打印a
                    case 10:
                        System.out.print("a");
                        break;  //此处break主要作用用于中断
                    //当i=11时打印b
                    case 11:
                        System.out.print("b");
                        break;  //此处break主要作用用于中断
                    //当i=12时打印c
                    case 12:
                        System.out.print("c");
                        break;  //此处break主要作用用于中断
                    //当i=13时打印d
                    case 13:
                        System.out.print("d");
                        break;  //此处break主要作用用于中断
                    //当i=14时打印e
                    case 14:
                        System.out.print("e");
                        break;  //此处break主要作用用于中断
                    //当i=15时打印f
                    case 15:
                        System.out.print("f");
                        break;  //此处break主要作用用于中断
                }
            }
            //使用内层for循环实现0-15列
            for (int j = 0; j <= 15; j++) {
                //打印+，\t为保证格式一致
                System.out.print("\t+\t");
            }

            System.out.println();
        }
        System.out.println();

    }


}
